#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
用户相关数据模型
"""

from sqlalchemy import Column, Integer, String, Boolean, DateTime
from sqlalchemy.orm import Session
from datetime import datetime
from typing import List, Optional
from .base import Base, BaseRepository, QueryCondition


class WebDAVUser(Base):
    """WebDAV用户表"""
    __tablename__ = 'webdav_users'
    
    id = Column(Integer, primary_key=True, autoincrement=True)
    username = Column(String(100), nullable=False, unique=True)
    password_hash = Column(String(255), nullable=False)  # 密码哈希
    is_active = Column(Boolean, default=True)
    root_path = Column(String(500), default='/')  # 用户根路径
    
    # 权限
    can_read = Column(Boolean, default=True)
    can_write = Column(Boolean, default=True)
    can_delete = Column(Boolean, default=True)
    
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    def check_password(self, password):
        """验证密码 - 支持多种哈希算法"""
        return self.verify_password(self.password_hash, password)
    
    @staticmethod
    def verify_password(password_hash, password):
        """静态方法：验证密码 - 支持多种哈希算法"""
        # 检查是否为bcrypt哈希（向后兼容）
        if password_hash.startswith('$2b$'):
            import bcrypt
            return bcrypt.checkpw(password.encode('utf-8'), password_hash.encode('utf-8'))
        
        # 检查是否为快速哈希（SHA256 + salt）
        if '$' in password_hash:
            import hashlib
            import hmac
            try:
                salt, expected_hash = password_hash.split('$', 1)
                actual_hash = hashlib.sha256((salt + password).encode('utf-8')).hexdigest()
                return hmac.compare_digest(actual_hash, expected_hash)
            except Exception:
                return False
        
        # 如果都不匹配，返回False
        return False
    
    @staticmethod
    def hash_password(password, use_fast_hash=True):
        """生成密码哈希
        
        Args:
            password: 明文密码
            use_fast_hash: 是否使用快速哈希（默认True），False时使用bcrypt
        """
        if use_fast_hash:
            # 使用SHA256 + 随机salt的快速哈希
            import hashlib
            import secrets
            salt = secrets.token_hex(16)  # 32字符的随机salt
            password_hash = hashlib.sha256((salt + password).encode('utf-8')).hexdigest()
            return f"{salt}${password_hash}"
        else:
            # 使用bcrypt（高安全性但较慢）
            import bcrypt
            return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')


class WebDAVUserRepository(BaseRepository):
    """WebDAV用户Repository"""
    
    def __init__(self):
        super().__init__(WebDAVUser)
    
    def find_by_username(self, username: str) -> Optional[WebDAVUser]:
        """根据用户名查找用户"""
        condition = QueryCondition()
        condition.eq(WebDAVUser.username, username)
        return self.get_one(condition)
    
    def find_active_users(self) -> List[WebDAVUser]:
        """查找活跃用户"""
        condition = QueryCondition()
        condition.eq(WebDAVUser.is_active, True)
        return self.list_by_condition(condition, order_by='username')
    
    def find_by_permissions(self, can_read: bool = None, can_write: bool = None, can_delete: bool = None) -> List[WebDAVUser]:
        """根据权限查找用户"""
        condition = QueryCondition()
        if can_read is not None:
            condition.eq(WebDAVUser.can_read, can_read)
        if can_write is not None:
            condition.eq(WebDAVUser.can_write, can_write)
        if can_delete is not None:
            condition.eq(WebDAVUser.can_delete, can_delete)
        return self.list_by_condition(condition, order_by='username')
    
    def create_user(self, username: str, password: str, root_path: str = '/', 
                   can_read: bool = True, can_write: bool = True, can_delete: bool = True) -> WebDAVUser:
        """创建用户"""
        user = WebDAVUser(
            username=username,
            password_hash=WebDAVUser.hash_password(password),
            root_path=root_path,
            can_read=can_read,
            can_write=can_write,
            can_delete=can_delete
        )
        return self.save(user)
    
    def authenticate(self, username: str, password: str) -> Optional[WebDAVUser]:
        """用户认证 - 优化版本"""
        import time
        start_time = time.time()
        
        try:
            user = self.find_by_username(username)
            if user and user.is_active and user.check_password(password):
                auth_time = time.time() - start_time
                if auth_time > 1.0:  # 认证时间超过1秒记录警告
                    print(f"⚠️  用户认证耗时过长: {username} ({auth_time:.3f}s)")
                return user
            return None
        except Exception as e:
            auth_time = time.time() - start_time
            print(f"❌ 用户认证异常: {username} ({auth_time:.3f}s) - {e}")
            return None
    
    def change_password(self, user_id: int, new_password: str) -> bool:
        """修改密码"""
        password_hash = WebDAVUser.hash_password(new_password)
        return self.update_by_id(user_id, password_hash=password_hash)
    
    def update_permissions(self, user_id: int, can_read: bool = None, 
                          can_write: bool = None, can_delete: bool = None) -> bool:
        """更新用户权限"""
        updates = {}
        if can_read is not None:
            updates['can_read'] = can_read
        if can_write is not None:
            updates['can_write'] = can_write
        if can_delete is not None:
            updates['can_delete'] = can_delete
        
        if updates:
            return self.update_by_id(user_id, **updates)
        return True
    
    def activate_user(self, user_id: int) -> bool:
        """激活用户"""
        return self.update_by_id(user_id, is_active=True)
    
    def deactivate_user(self, user_id: int) -> bool:
        """停用用户"""
        return self.update_by_id(user_id, is_active=False)